#ifndef PESAGEMCONTROLLER_H
#define PESAGEMCONTROLLER_H

#include <QObject>
#include <QThread>
#include <QString>
#include <QHash>
#include <QSemaphore>

#include "dao/pesagemdao.h"
#include "dispositivos/balanca.h"
#include "utils/conf.h"
#include "backgroundworker.h"
#include <unistd.h>

#define DEFAULT_INTERVALO_PESAGEM 0.2

#define MODELO_BALANCA_FILIZOLA_CS "FILIZOLA_CS"
#define MODELO_BALANCA_FILIZOLA_IDM "FILIZOLA_IDM"
#define MODELO_BALANCA_FILIZOLA_PLURIS "FILIZOLA_PLURIS"
#define MODELO_BALANCA_FILIZOLA_MFC "FILIZOLA_MFC"

class PesagemWorker;


class PesagemController : public QObject
{
    typedef enum {
        NAO_EXISTE_PRODUTO,
        RECIPIENTE_INFORMADO_INCORRETAMENTE,
        PESO_INSTAVEL,
        PESO_VALIDO
    } ValidacaoPesoResult;

    typedef struct {
        QString mensagem;
        int severidade;
    } PesagemErrors;

    static PesagemErrors pesagemErrors[3];

    Q_OBJECT

    Q_PROPERTY(Conf* conf READ conf WRITE setConf)
public:
    explicit PesagemController(QObject *parent = 0);
    ~PesagemController();

    Conf* conf();
    void setConf(Conf* conf);

    Q_INVOKABLE Balanca* __get_balanca();
    Q_INVOKABLE ValidacaoPesoResult validar_peso(double peso_total, double tara);

    Q_INVOKABLE void salvarPesagem (double peso_total, qulonglong id_depoperacao, qulonglong id_depprod,
                                    qulonglong codprod, QString produto, qulonglong id_deppanela,
                                    qulonglong codpanela, QString panela, double tara);
    Q_INVOKABLE void salvar_pesagem(double peso_total, qulonglong id_depoperacao, qulonglong id_depprod,
                                    qulonglong codprod, QString produto, qulonglong id_deppanela,
                                    qulonglong codpanela, QString panela, double tara);

    Q_INVOKABLE void iniciar_leitura_balanca();
    Q_INVOKABLE void parar_leitura_balanca();

    bool lerBalanca();

signals:
    void saveError(QString mensagem, int severidade);
    void saveSuccess();
    void novaLeitura(QVariantMap dados);

public slots:

private:
    Balanca* balanca;
    QSemaphore *sema;
    PesagemDAO* pesagemDAO;
    Conf* m_conf;
    PesagemWorker* worker;
    bool lendoBalanca;
};

class PesagemWorker: public BackgroundWorker
{
    Q_OBJECT

public:
    explicit PesagemWorker(QObject *parent, PesagemController *pesagemController)
        : BackgroundWorker(parent)
    {
        this->pesagemController = pesagemController;
    }

public slots:
    void lerBalanca() {
        while(pesagemController->lerBalanca());
        this->deleteLater();
    }

    void salvarPesagem() {
        pesagemController->salvarPesagem(this->args.value("peso_total").toDouble(),
                                         this->args.value("id_depoperacao").toULongLong(),
                                         this->args.value("id_depprod").toULongLong(),
                                         this->args.value("codprod").toULongLong(),
                                         this->args.value("produto").toString(),
                                         this->args.value("id_deppanela").toULongLong(),
                                         this->args.value("codpanela").toULongLong(),
                                         this->args.value("panela").toString(),
                                         this->args.value("tara").toDouble());
        this->deleteLater();
    }

private:
    PesagemController *pesagemController;
};

#endif // PESAGEMCONTROLLER_H
